﻿#include "CurveAssetCreator.h"

#include "AssetToolsModule.h"
#include "JsonObjectConverter.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "EditorFramework/AssetImportData.h"
#include "UObject/SavePackage.h"

bool FCurveAssetCreator::CreateAllCurveAssetsFromJsonFile(const FString& InJsonFilePath)
{
	FString JsonString;
	if (!ensureMsgf(FFileHelper::LoadFileToString(JsonString, *InJsonFilePath)
	                , TEXT("无法读取Json文件: %s")
	                , *InJsonFilePath))
	{
		return false;
	}

	return CreateAllCurveAssetFromJsonString(JsonString);
}

bool FCurveAssetCreator::CreateAllCurveAssetFromJsonString(const FString& InJsonString)
{
	// 反序列化整个Json字符串
	TSharedPtr<FJsonObject> JsonObject;
	TSharedRef<TJsonReader<>> Reader = TJsonReaderFactory<>::Create(InJsonString);
	if (!ensureMsgf(FJsonSerializer::Deserialize(Reader, JsonObject), TEXT("Json数据格式错误")))
	{
		return false;
	}

	// 检查Json对象是否有效
	if (!ensureMsgf(JsonObject.IsValid(), TEXT("Json数据格式错误")))
	{
		return false;
	}

	// 获取所有曲线对象
	const TArray<TSharedPtr<FJsonValue>>* CurvesArray;
	if (!ensureMsgf(JsonObject->TryGetArrayField("Curves", CurvesArray), TEXT("Json数据格式错误")))
	{
		return false;
	}

	// 遍历每个曲线对象的Json字符串并创建资产
	for (const auto& CurveValue : *CurvesArray)
	{
		TSharedPtr<FJsonObject> CurveObject = CurveValue->AsObject();
		if (!ensureMsgf(CurveObject.IsValid(), TEXT("Json数据格式错误")))
		{
			continue;
		}

		if (!CreateOneCurveAssetFromJsonData(CurveObject))
		{
			UE_LOG(LogTemp, Warning, TEXT("创建曲线资产失败"));
			return false;
		}
	}

	return true;
}

bool FCurveAssetCreator::CreateOneCurveAssetFromJsonData(const TSharedPtr<FJsonObject>& InJsonData)
{
	// 创建新UCurveFloat资产
	UCurveFloat* NewCurve = NewObject<UCurveFloat>();
	if (!ensureMsgf(nullptr != NewCurve, TEXT("创建UCurveFloat资产失败")))
	{
		return false;
	}

	// 获取关键帧数据并添加到曲线中
	const TArray<TSharedPtr<FJsonValue>>* KeyframesArray;
	if (!ensureMsgf(InJsonData->TryGetArrayField("Keyframes", KeyframesArray)
	                , TEXT("Json数据格式错误，未找到关键帧数组")))
	{
		return false;
	}

	// 反序列化每个关键帧对象并添加到曲线中
	TArray<FRichCurveKey> AllKeyFrames;
	for (const auto& KeyframeValue : *KeyframesArray)
	{
		TSharedPtr<FJsonObject> KeyframeObject = KeyframeValue->AsObject();
		if (!ensureMsgf(KeyframeObject.IsValid(), TEXT("Json数据格式错误")))
		{
			continue;
		}

		FRichCurveKey Keyframe;
		FString KeyframeJson;
		TSharedRef<TJsonWriter<>> Writer = TJsonWriterFactory<>::Create(&KeyframeJson);
		FJsonSerializer::Serialize(KeyframeObject.ToSharedRef(), Writer);

		// 使用JsonObjectStringToUStruct进行反序列化
		FJsonObjectConverter::JsonObjectStringToUStruct<FRichCurveKey>(KeyframeJson, &Keyframe, 0, 0);

		AllKeyFrames.Add(Keyframe);
	}

	NewCurve->FloatCurve.SetKeys(AllKeyFrames);

	FString FolderPath = InJsonData->GetStringField("Folder");
	FString FileName = InJsonData->GetStringField("FileName");
	FString FullAssetPath = FString::Printf(TEXT("%s/%s.UAsset"), *FolderPath, *FileName);
	return SaveObjectToAsset(*NewCurve, FullAssetPath);
}

bool FCurveAssetCreator::SaveObjectToAsset(UObject& InObject, const FString& InAssetPath)
{
	FString FolderPath = FPaths::GetPath(InAssetPath);
	FString AssetName = FPaths::GetCleanFilename(InAssetPath);
	FString AssetBaseName = FPaths::GetBaseFilename(AssetName);
	FString PackageName = FPaths::Combine(FolderPath, *AssetBaseName);

	// 确保包路径是虚拟路径，并且符合Unreal的命名规范
	if (!ensureMsgf(FPackageName::IsValidLongPackageName(PackageName, true)
	                , TEXT("Invalid package name: %s"), *PackageName))
	{
		return false;
	}

	FolderPath = FPaths::Combine(FPaths::ProjectDir(), FolderPath);
	FolderPath = FPaths::ConvertRelativePathToFull(FolderPath);
	if (!FPaths::DirectoryExists(FolderPath))
	{
		// 创建文件夹
		IPlatformFile& PlatformFile = FPlatformFileManager::Get().GetPlatformFile();
		if (!ensureMsgf(PlatformFile.CreateDirectoryTree(*FolderPath)
		                , TEXT("创建文件夹失败: %s"), *FolderPath))
		{
			return false;
		}
	}

	// 检查包是否已存在
	UPackage* Package = FindPackage(nullptr, *InAssetPath);
	if (nullptr == Package)
	{
		Package = CreatePackage(*PackageName);
	}

	if (!ensureMsgf(nullptr != Package, TEXT("创建包失败")))
	{
		return false;
	}

	// 设置适当的标志
	InObject.SetFlags(RF_Public | RF_Standalone);

	// 将对象的outer设置为Package
	InObject.Rename(*AssetBaseName, Package, REN_DontCreateRedirectors | REN_NonTransactional);

	// 使用资产工具保存
	FAssetRegistryModule::AssetCreated(&InObject);

	// 构建保存参数
	FSavePackageArgs SaveArgs;
	SaveArgs.TopLevelFlags = EObjectFlags::RF_Public | EObjectFlags::RF_Standalone;
	SaveArgs.Error = GError;
	SaveArgs.SaveFlags = SAVE_None;

	// 保存包
	if (!ensureMsgf(UPackage::SavePackage(Package, &InObject, *InAssetPath, SaveArgs)
	                , TEXT("保存包失败")))
	{
		return false;
	}

	if (!ensureMsgf(InObject.MarkPackageDirty(), TEXT("标记包为脏失败")))
	{
		return false;
	}

	return true;
}
